package com.asura.ops.sync.server.controller.web;

import com.asura.ops.sync.server.model.entity.CfgMqEntity;
import com.asura.ops.sync.server.model.entity.req.RepushByClientCodeReq;
import com.asura.ops.sync.server.model.entity.req.RepushReq;
import com.asura.ops.sync.server.model.entity.res.BaseResultCodeEnum;
import com.asura.ops.sync.server.model.entity.res.ResponseBase;
import com.asura.ops.sync.server.model.entity.vo.ThreadVo;
import com.asura.ops.sync.server.monitor.ThreadMonitor;
import com.asura.ops.sync.server.service.ManageService;
import com.asura.ops.sync.server.sync.DebeziumTools;
import com.asura.ops.sync.server.sync.model.OffsetInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.List;

/**
 * @author: zouyang
 * @date: 2022/8/2
 * @description: 测试controller
 */
@RestController
@RequestMapping("/manage")
@Slf4j
@Api(value = "ManageController", tags = "管理端接口")
public class ManageController {

    @Autowired
    private ManageService manageService;

    @Autowired
    private ThreadMonitor threadMonitor;

    @GetMapping("/start")
    public ResponseBase start(@RequestParam("serverId") String serverId) {
        ResponseBase responseBase = DebeziumTools.start(serverId, false);
        if (responseBase.getCode() == BaseResultCodeEnum.SUCCESS.getCode()) {
            threadMonitor.addListenServer(serverId);
        }
        return responseBase;
    }

    @GetMapping("/stop")
    public ResponseBase stop(@RequestParam("serverId") String serverId) throws IOException {
        ResponseBase responseBase = DebeziumTools.stop(serverId);
        if (responseBase.getCode() == BaseResultCodeEnum.SUCCESS.getCode()) {
            threadMonitor.removeListenServer(serverId);
        }
        return responseBase;
    }

    @GetMapping("/restart")
    public ResponseBase restart(@RequestParam("serverId") String serverId) throws IOException {
        DebeziumTools.refresh(serverId);
        return ResponseBase.success();
    }

    @PostMapping("/changeOffset")
    @ApiOperation(value = "修改offset")
    public ResponseBase changeOffset(@RequestParam("serverId") String serverId, @RequestBody OffsetInfo offsetInfo) throws IOException {
        DebeziumTools.changeOffset(serverId, offsetInfo);
        return ResponseBase.success();
    }


    @PostMapping("/repush")
    @ApiOperation(value = "补偿推送")
    public ResponseBase repush(@RequestBody RepushReq repushReq) throws IOException {
        if (ObjectUtils.isEmpty(repushReq.getStartTime()) || ObjectUtils.isEmpty(repushReq.getEndTime())) {
            return ResponseBase.fail("参数非法 startTime | endTime 是空");
        }

        if (ObjectUtils.isEmpty(repushReq.getClients())) {
            return ResponseBase.fail("参数非法 clients 是空");
        }

        for (CfgMqEntity mqEntity : repushReq.getClients()) {
            if (ObjectUtils.isEmpty(mqEntity.getExchangeName())
                    || ObjectUtils.isEmpty(mqEntity.getSyncTableName())
                    || ObjectUtils.isEmpty(mqEntity.getSyncDbName())
                    || ObjectUtils.isEmpty(mqEntity.getRouteKey())
                    || ObjectUtils.isEmpty(mqEntity.getSyncClientCode())) {
                return ResponseBase.fail("参数非法 exchangeName | syncTableName | syncDbName | routeKey | syncClientCode 是空");
            }
        }

        manageService.repush(repushReq);

        return ResponseBase.success();
    }

    @GetMapping("/repushByClientCode")
    @ApiOperation(value = "补偿推送,根据客户端全量推送表")
    public ResponseBase repushByClientCode(@RequestParam("clientCode") String clientCode, @RequestParam("updateTimeFieldName") String updateTimeFieldName) throws IOException {
        if (ObjectUtils.isEmpty(clientCode)) {
            return ResponseBase.fail("参数非法 clientCode 是空");
        }

        manageService.repushByClientCode(clientCode, updateTimeFieldName);

        return ResponseBase.success();
    }

    @PostMapping("/repushByClientCodeV2")
    @ApiOperation(value = "补偿推送,根据客户端全量推送表")
    public ResponseBase repushByClientCodeV2(@RequestBody RepushByClientCodeReq repushByClientCodeReq) throws IOException {
        if (ObjectUtils.isEmpty(repushByClientCodeReq.getClientCode())) {
            return ResponseBase.fail("参数非法 clientCode 是空");
        }

        manageService.repushByClientCodeV2(repushByClientCodeReq);

        return ResponseBase.success();
    }

    @GetMapping("/cleanChangeInfo")
    @ApiOperation(value = "清理指定时间之前的发送记录")
    public ResponseBase cleanChangeInfo(@RequestParam("time") String time) throws IOException {
        if (ObjectUtils.isEmpty(time)) {
            return ResponseBase.fail("参数非法 time 是空");
        }

        manageService.cleanChangeInfo(time);

        return ResponseBase.success();
    }

    @GetMapping("/setCleanSwitch")
    @ApiOperation(value = "设置清理开关")
    public ResponseBase setCleanSwitch(@RequestParam("cleanSwitch") Boolean cleanSwitch) throws IOException {
        if (ObjectUtils.isEmpty(cleanSwitch)) {
            return ResponseBase.fail("参数非法 cleanSwitch 是空");
        }

        manageService.setCleanSwitch(cleanSwitch);

        return ResponseBase.success();
    }

    @GetMapping("/checkThreadMonitor")
    @ApiOperation(value = "设置清理开关")
    public ResponseBase checkThreadMonitor() throws IOException {
        List<ThreadVo> result = threadMonitor.checkThreadActive();
        return ResponseBase.success(result);
    }
}
